Public Const GWL_WNDPROC = (-4)
Public Const WM_MOVE = &H3
Public Const ABE_BOTTOM = 3
Public Const ABE_LEFT = 0
Public Const ABE_RIGHT = 2
Public Const ABE_TOP = 1
Public Const ABM_GETTASKBARPOS = &H5
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOZORDER = &H4
Public Const SWP_NOSENDCHANGING = &H400
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public Type APPBARDATA
cbSize As Long
hwnd As Long
uCallbackMessage As Long
uEdge As Long
rc As RECT
lParam As Long
End Type
Public Declare Function SHAppBarMessage Lib "shell32.dll" (ByVal dwMessage As Long, pData As APPBARDATA) As Long
Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Public Declare Function GetLastError Lib "kernel32" () As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public trayBar As APPBARDATA
Public lProcOld As Long
Public appRect As RECT, deskRect As RECT
Public Const margine = 20 ' n. di pixel di margine
' Subclassing per la gestione dell'evento WM_MOVE generato durante gli spostamenti del form
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim w As Long, h As Long
Dim move As Boolean
If uMsg = WM_MOVE Then
If (GetWindowRect(hwnd, appRect)) Then
w = appRect.Right - appRect.Left
h = appRect.Bottom - appRect.Top
If Not (w < deskRect.Right) And Not (h < deskRect.Bottom) Then
Exit Function
End If
move = False
If (Abs(appRect.Top - deskRect.Top) <= margine) Then
appRect.Top = deskRect.Top
move = True
End If
If (Abs(appRect.Left - deskRect.Left) <= margine) Then
appRect.Left = deskRect.Left
move = True
End If
If (Abs(appRect.Bottom - deskRect.Bottom) <= margine) Then
appRect.Top = deskRect.Bottom - h
move = True
End If
If (Abs(appRect.Right - deskRect.Right) <= margine) Then
appRect.Left = deskRect.Right - w
move = True
End If
If move Then
SetWindowPos hwnd, 0, appRect.Left, appRect.Top, 0, 0, SWP_NOSIZE Or SWP_NOZORDER 'Or SWP_NOSENDCHANGING
End If
Else
Debug.Print GetLastError()
End If
End If
WindowProc = CallWindowProc(lProcOld, hwnd, uMsg, wParam, lParam)
End Function
Public Function GetDesktopRect(ByRef lpRect As RECT) As Long
Dim sz As RECT
Dim ret As Long
trayBar.cbSize = Len(trayBar)
trayBar.hwnd = FindWindow("Shell_TrayWnd", 0)
' calcola le dim. e la posizione della barra degli strumenti
ret = SHAppBarMessage(ABM_GETTASKBARPOS, trayBar)
sz = trayBar.rc
' calcola le dim. dello schermo
GetWindowRect GetDesktopWindow(), lpRect
' calcola le dim. effettive del desktop
Select Case trayBar.uEdge
Case ABE_TOP
lpRect.Top = sz.Bottom
Case ABE_LEFT
lpRect.Left = sz.Right
Case ABE_RIGHT
lpRect.Right = sz.Left
Case ABE_BOTTOM
lpRect.Bottom = sz.Top
End Select
End Function
Uso :
...
Private Sub Form_Load()
GetDesktopRect deskRect
lProcOld = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Private Sub Form_Unload(Cancel As Integer)
SetWindowLong Me.hwnd, GWL_WNDPROC, lProcOld
End Sub
...
|